function nsph = srf_ApplySSM(hfile, ssm, sphere, smiter)
% SRF::ApplySSM  - apply SSM file on vertex coordinates
%
% FORMAT:       sph = srf.ApplySSM(ssm, sphere [, smiter])
%
% Input fields:
%
%       srf         folded mesh (e.g. RECOSM mesh)
%       ssm         SSM mapping to sphere mesh
%       sphere      sphere mesh SRF used for mapping
%       smiter      number of smoothing steps (default = 20, force 0.03)
%
% Output fields:
%
%       sph         SPH mesh with NrOfVertices of sphere, folded as srf

% Version:  v0.7f
% Build:    8110521
% Date:     Nov-05 2008, 9:00 PM CET
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% check arguments
if nargin < 3 || ...
    numel(hfile) ~= 1 || ...
   ~isBVQXfile(hfile, 'srf') || ...
    numel(ssm) ~= 1 || ...
   ~isBVQXfile(ssm, 'ssm') || ...
    numel(sphere) ~= 1 || ...
   ~isBVQXfile(sphere, 'srf')
    error( ...
        'BVQXfile:BadArguments', ...
        'Invalid call to %s.', ...
        mfilename ...
    );
end
if nargin < 4 || ...
    numel(smiter) ~= 1 || ...
   ~isa(smiter, 'double') || ...
    isinf(smiter) || ...
    isnan(smiter) || ...
    smiter < 0 || ...
    smiter > 3000
    smiter = 20;
else
    smiter = round(smiter);
end

% get contents
fldc = bvqxfile_getcont(hfile.L);
ssmc = bvqxfile_getcont(ssm.L);
sphc = bvqxfile_getcont(sphere.L);

% check numbers
if numel(ssmc.SourceOfTarget) ~= size(sphc.VertexCoordinate, 1)
    error( ...
        'BVQXfile:BadArgument', ...
        'SSM and Sphere mesh must match.' ...
    );
end
ssmc = ssmc.SourceOfTarget;

% create new SRF from folded mesh
nsph = bless(aft_CopyObject(hfile), 1);
nspc = bvqxfile_getcont(nsph.L);

% neighbors and coords
crd = nspc.VertexCoordinate(ssmc, :);
nei = sphc.Neighbors;
tri = sphc.TriangleVertex;

% perform smoothing
opts = struct( ...
    'type',  'smooth', ...
    'force', 0.03, ...
    'niter', smiter, ...
    'areac', 0);
crd = mesh_morph(crd, nei, tri, opts);

% make settings
nspc.ExtendedNeighbors = sphc.ExtendedNeighbors;
nspc.NrOfVertices = sphc.NrOfVertices;
nspc.NrOfTriangles = size(tri, 1);
nspc.VertexCoordinate = crd;
nspc.VertexNormal = nspc.VertexNormal(ssmc, :);
nspc.VertexColor = nspc.VertexColor(ssmc, :);
nspc.Neighbors = nei;
nspc.TriangleVertex = tri;
nspc.NrOfTriangleStrips = sphc.NrOfTriangleStrips;
nspc.TriangleStripSequence = sphc.TriangleStripSequence;
nspc.AutoLinkedMTC = '<none>';

% set back in global memory array
bvqxfile_setcont(nsph.L, nspc);
